//@author A0105730U
#include "DateTimeLocator.h"


DateTimeLocator::DateTimeLocator(void)
{
}


DateTimeLocator::~DateTimeLocator(void)
{
}


//@author A0105730U
//clear spaces and some punctuations in suffix and prefix of the input string 
std::string DateTimeLocator::clear_Space_Punctuation(std::string input){
	size_t pos1 = input.find_first_not_of(NOT_FOUND_STRING_LOCATOR);
	size_t pos2 = input.find_last_not_of(NOT_FOUND_STRING_LOCATOR);

	if(pos1 == std::string::npos){
		return QUOTE_LOCATOR;
	}

	return input.substr(pos1, pos2-pos1+1);
}


//@author A0105730U
//clear spaces and some punctuations in suffix and prefix of the input string. After clearing, ensure at least one space is left.
std::string DateTimeLocator::clear_Space_Punctuation_WithASpaceLeft(std::string input){
	size_t pos1 = input.find_first_not_of(NOT_FOUND_STRING_LOCATOR);
	size_t pos2 = input.find_last_not_of(NOT_FOUND_STRING_LOCATOR);

	if(pos1 == std::string::npos){
		return QUOTE_BLANK_LOCATOR;
	}

	return input.substr(pos1, pos2-pos1+1);
}

//@author A0105730U
//detect all time pieces and store the positions and contents of these pieces.
void DateTimeLocator::detectTimePiece(std::string input, size_t& prePos, std::vector<std::string>& timeVec, std::vector<size_t>& stVec, std::vector<size_t>& edVec){
	bool dummy;
	TimeParser tp;
	size_t stPos;
	size_t edPos;
	std::string timestring;
	std::string pre_fix;
	std::string suf_fix;
	if(tp.parse(input, timestring, stPos, edPos)){

		stVec.push_back(stPos + prePos);
		edVec.push_back(edPos + prePos);
		timeVec.push_back(timestring);

		pre_fix = input.substr(0, stPos);
		suf_fix = input.substr(edPos+1, input.size()-edPos-1);

		detectTimePiece(pre_fix, prePos, timeVec, stVec, edVec);    
		prePos = prePos + edPos + 1;
		detectTimePiece(suf_fix, prePos, timeVec, stVec, edVec);
	}
}


//@author A0105730U
//detect all date pieces and store the positions and contents of these pieces.
void DateTimeLocator::detectDatePiece(std::string input, size_t& prePos, std::vector<std::string>& dateVec, std::vector<size_t>& stVec, std::vector<size_t>& edVec){

	DateParser dp;
	size_t stPos;
	size_t edPos;
	std::string datestring;
	std::string pre_fix;
	std::string suf_fix;
	if(dp.parse(input, datestring, stPos, edPos)){

		stVec.push_back(stPos + prePos);
		edVec.push_back(edPos + prePos);
		dateVec.push_back(datestring);

		pre_fix = input.substr(0, stPos);
		suf_fix = input.substr(edPos+1, input.size()-edPos-1);

		detectDatePiece(pre_fix, prePos, dateVec, stVec, edVec);
		prePos = prePos + edPos + 1;
		detectDatePiece(suf_fix, prePos, dateVec, stVec, edVec);
	}
}







//@author A0105730U
//check whether the piece of input string (from start position to end position) is consist of only prepositions and spaces
bool DateTimeLocator::ConsistOfPrepositionOrSpace(std::string input, std::size_t start, std::size_t end){

	std::smatch match;

	std::string substring = input.substr(start+1,end-start-1);
	substring = clear_Space_Punctuation_WithASpaceLeft(substring); //clear all 
	if(std::regex_match(substring, match, proposition)){
		return true;
	}
	return false;
}

//@author A0105730U
//get default end time when user didn't type in the endtime.
std::string DateTimeLocator::getDefaultEndTime(std::string startTime){
	std::istringstream in(startTime);
	std::ostringstream out;
	int hour;
	int mins;
	char c;
	in >> hour >> c >> mins;
	hour++;        //next hour

	if(hour > 23){
		return TWO_THREE_FIVE_NINE_LOCATOR;
	}else{
		out << hour << ":" << (mins<10 ? ZERO_STRING : QUOTE) << mins;
		return out.str();
	}
}





//@author A0105730U
/*This function takes in start positions and end positions of all possible time/date pieces and decide which pieces of date/time should be intepreted as real date/time.
It return false when it is confused about which date/time pieces to be read.
It return true when it determines the real date/time pieces successfully and pass back the positions of real date/time pieces by reference.

It read date/time pieces successfully and not gets confused when 
1. Number of possible date pieces is from 0 to 2.
2. Number of possible time pieces is from 0 to 2.
3. Majority of date/time pieces are conjucted with each other by prepositions or spaces (All peices are stick to each other or 2 pieces are together while one peice is apart 
*/

//@author A0105730U
bool DateTimeLocator::LocateDateTimeWithoutConfusion (std::string input, std::vector<size_t>& stPosToDelete, std::vector<size_t> timePosS, std::vector<size_t> timePosE, std::vector<size_t> datePosS, std::vector<size_t> datePosE, size_t &datetimeGroupS, size_t &datetimeGroupE){

	std::vector<size_t> startPos_All;
	std::vector<size_t> endPos_All;
	std::vector<size_t> count;
	std::vector<size_t> endPos_All_isGrouped;
	std::vector<size_t> startPos_All_isGrouped;

	datetimeGroupS = 0;     //start and end positions of the group of real datetime pieces
	datetimeGroupE = 0;


	if(timePosS.size()==0&&datePosS.size()==0){   //Locator is not confused and no need to locate times or dates when no times or dates are found
		return true;
	}

	if(timePosS.size()>2||datePosS.size()>2){     //Locator is confused when more than two pieces of dates or times are found
		return false;
	}



	/* Store all start and end positions of date/time pieces respectively in startPos_All and endPos_All    */

	for(int i = 0 ; i < timePosS.size() ; i ++ ){                 
		startPos_All.push_back(timePosS[i]);
	}

	for(int i = 0 ; i < datePosS.size() ; i ++ ){
		startPos_All.push_back(datePosS[i]);
	}

	for(int i = 0 ; i < timePosE.size() ; i ++ ){
		endPos_All.push_back(timePosE[i]);
	}

	for(int i = 0 ; i < datePosE.size() ; i ++ ){
		endPos_All.push_back(datePosE[i]);
	}

	/**************************************************************************************************************/



	sort(endPos_All.begin(),endPos_All.end());
	sort(startPos_All.begin(),startPos_All.end());




	/****************************************************detect groups of date/time pieces. **********************************************/
	/*
	date/time pieces are considered a group when they are conjuncted with preposition and spaces only. 
	Let Si and Ei be the positions of i th date/time piece, store all. 
	form groups by determining whether string between Ei and Si+1 is only consist of preposition and space.
	Use vector<size_t> start/endPos_All_isGrouped to store positions of all groups.
	*/
	for(int i = 0 ; i < endPos_All.size()-1 ; i ++ ){
		if(ConsistOfPrepositionOrSpace(input,endPos_All[i],startPos_All[i+1])){    //Determine whether two pieces(string between Ei and Si+1) are conjuncted with prepositions or spaces only
			if(startPos_All_isGrouped.empty()){
				endPos_All_isGrouped.push_back(startPos_All[i]);
				startPos_All_isGrouped.push_back(endPos_All[i+1]);
			}
			else if(endPos_All[i] != startPos_All_isGrouped.back()){
				endPos_All_isGrouped.push_back(startPos_All[i]);
				startPos_All_isGrouped.push_back(endPos_All[i+1]);
			}
			else{
				startPos_All_isGrouped.pop_back();
				startPos_All_isGrouped.push_back(endPos_All[i+1]);

			}

		}
		else{
			if(endPos_All_isGrouped.size() == 0 || endPos_All[i] != startPos_All_isGrouped.back()){
				endPos_All_isGrouped.push_back(startPos_All[i]);
				startPos_All_isGrouped.push_back(endPos_All[i]);
			}
			if(i == endPos_All.size() - 2){
				endPos_All_isGrouped.push_back(startPos_All[i+1]);
				startPos_All_isGrouped.push_back(endPos_All[i+1]);
			}
		}
	}
	/********************************************************************************************************************************************/



	if(startPos_All.size() == 1){                       //There is only one date/time pieces found
		datetimeGroupS=startPos_All.front();
		datetimeGroupE=endPos_All.front();
		return true;
	}


	if(startPos_All_isGrouped.size()==1){              //There is only one group of date/time pieces found
		datetimeGroupS=endPos_All_isGrouped.front();
		datetimeGroupE=startPos_All_isGrouped.front();
		return true;
	}else if(startPos_All_isGrouped.size()==2){        //More than two groups are found and decide which group to be read
		for(int i = 0 ; i < startPos_All_isGrouped.size() ; i ++ ){
			int k = 0;
			for(int j = 0 ; j < startPos_All.size() ; j ++ ){
				if(startPos_All[j]>=endPos_All_isGrouped[i] && startPos_All[j] <= startPos_All_isGrouped[i]){
					k ++;
				}
			}
			count.push_back(k);


		}
		if(count.size() == 1){
			count.push_back(-1);
		}




		/**************compare the number of date/time pieces consisted in two groups, and decide which group to read***************/
		if(count[0]==count[1]){                  //Two groups have same number of date/time pieces, confused and return false!
			return false;
		}
		else if(count[0]>count[1]){
			stPosToDelete.push_back(endPos_All_isGrouped.back());
			startPos_All_isGrouped.pop_back();
			endPos_All_isGrouped.pop_back();

			datetimeGroupS=endPos_All_isGrouped.front();
			datetimeGroupE=startPos_All_isGrouped.front();
			return true;
		}
		else if(count[1]>count[0]){
			stPosToDelete.push_back(endPos_All_isGrouped.front());
			startPos_All_isGrouped[0]=startPos_All_isGrouped[1];
			endPos_All_isGrouped[0]=endPos_All_isGrouped[1];
			startPos_All_isGrouped.pop_back();
			endPos_All_isGrouped.pop_back();
			datetimeGroupS=endPos_All_isGrouped.front();
			datetimeGroupE=startPos_All_isGrouped.front();
			return true;
		}
		/*****************************************************************************************************************************/



	}else if(startPos_All_isGrouped.size()==3){  //When there are three groups, confused and return false if three groups has same size of 1; return true if one of the group'size is two and read this group
		for(int i = 0 ; i < startPos_All_isGrouped.size() ; i ++ ){
			int k = 0;
			for(int j = 0 ; j < startPos_All.size() ; j ++ ){
				if(startPos_All[j]>=endPos_All_isGrouped[i] && startPos_All[j] <= startPos_All_isGrouped[i]){
					k ++;
				}
			}
			count.push_back(k);	
		}

		for(int i = 0 ; i < count.size() ; i ++ ){
			if(count[i] == 2){

				datetimeGroupS=endPos_All_isGrouped[i];
				datetimeGroupE=startPos_All_isGrouped[i];

			}else{
				stPosToDelete.push_back(endPos_All_isGrouped[i]);
			}
		}

		if(stPosToDelete.size() == 2){
			return true;
		}

		return false;




	}else{    //more than three groups are found, confused and return false!
		return false;
	}


}


//@author A0105730U
//return the last word before the date/time group
std::string DateTimeLocator::getWordBeforeGroup(std::string input, size_t dtGroupS){
	std::string pre_fix = input.substr(0, dtGroupS);
	size_t pos2 = pre_fix.find_last_not_of(' ');

	if(pos2 == std::string::npos){
		pos2 = dtGroupS - 1;
	}

	pre_fix = pre_fix.substr(0, pos2+1);
	size_t pos1 = pre_fix.find_last_of(' ');                      

	if(pos1 == std::string::npos){
		pos1 = 0;
	}else{
		pos1 = pos1 + 1;
	}

	return input.substr(pos1, pos2-pos1+1);
}





//@author A0105730U
//get the name from input string
//Name is the input string with the group of date/time pieces extracted.   
std::string DateTimeLocator::getName(std::string input, size_t dtGroupS, size_t dtGroupE){
	std::string name;
	std::smatch match;

	if(dtGroupS == dtGroupE){
		name = input;
		return name;
	}

	std::string pre_fix = input.substr(0, dtGroupS);
	size_t pos2 = pre_fix.find_last_not_of(' ');

	if(pos2 == std::string::npos){
		pos2 = dtGroupS - 1;
	}

	pre_fix = pre_fix.substr(0, pos2+1);
	size_t pos1 = pre_fix.find_last_of(' ');                     

	if(pos1 == std::string::npos){
		pos1 = 0;
	}else{
		pos1 = pos1 + 1;
	}

	std::string target = pre_fix.substr(pos1, pos2-pos1+1);

	if(regex_match(target, match, proposition)){
		dtGroupS = pos1;
	}

	std::string pre = input.substr(0, dtGroupS-0);
	std::string post = input.substr(dtGroupE+1, input.size()-dtGroupE-1);



	if(pre.size()>0){
		if(pre.at(pre.size()-1) == ' '){
			pre = pre.substr(0, pre.size()-1);
		}
	}

	name = pre + post;

	return name;

}


//@author A0105730U

//Read the dates and times from the input string, and extract the name.
bool DateTimeLocator::process(std::string input, std::string& name, std::string& startT, std::string& endT,std::string& date1, std::string& date2){
	size_t prePos;
	
	DateParser dateP;
	TimeParser timeP;
	std::vector<std::string> timeVec;
	std::vector<std::string> dateVec;
	std::vector<size_t> posTimeS;  
	std::vector<size_t> posTimeE; 
	std::vector<size_t> posDateS;  
	std::vector<size_t> posDateE;
	size_t dtGroupS;
	size_t dtGroupE;

	detectTimePiece(input, prePos=0, timeVec, posTimeS, posTimeE);    //detect all time pieces and store the positions and contents of these pieces.

	detectDatePiece(input, prePos=0, dateVec, posDateS, posDateE);    //detect all date pieces and store the positions and contents of these pieces.



	std::vector<size_t> stPosToDelete;
	if(!LocateDateTimeWithoutConfusion (input, stPosToDelete, posTimeS, posTimeE, posDateS, posDateE, dtGroupS, dtGroupE)){
		return false;
	}


	/*************clear obsolete date/time pieces***********************/
	for(int j = 0; j < stPosToDelete.size(); j ++){

		int i = 0;
		for(i=0; i<posTimeS.size();i++){
			if(stPosToDelete[j] == posTimeS[i]){
				posTimeS.erase(posTimeS.begin()+i);
				posTimeE.erase(posTimeE.begin()+i);
				timeVec.erase(timeVec.begin()+i);
				i--;
			}


		}

		i = 0;
		for(i=0;i<posDateS.size();i++){
			if(stPosToDelete[j] == posDateS[i]){
				posDateS.erase(posDateS.begin()+i);
				posDateE.erase(posDateE.begin()+i);
				dateVec.erase(dateVec.begin()+i);
				i--;
			}
		}

	}
	/******************************************************************/





	/*Correct the order of positions of date/time pieces if there are two date/time pieces found*/
	if(posDateS.size() == 2){
		if(posDateS[0] > posDateS[1]){
			size_t tempI;
			std::string tempS;

			tempI = posDateS[0];
			posDateS[0] = posDateS[1];
			posDateS[1] = tempI;

			tempI = posDateE[0];
			posDateE[0] = posDateE[1];
			posDateE[1] = tempI;

			tempS = dateVec[0];
			dateVec[0] = dateVec[1];
			dateVec[1] = tempS;
		}
	}

	if(posTimeS.size() == 2){
		if(posTimeS[0] > posTimeS[1]){
			size_t tempI;
			std::string tempS;

			tempI = posTimeS[0];
			posTimeS[0] = posTimeS[1];
			posTimeS[1] = tempI;

			tempI = posTimeE[0];
			posTimeE[0] = posTimeE[1];
			posTimeE[1] = tempI;

			tempS = timeVec[0];
			timeVec[0] = timeVec[1];
			timeVec[1] = tempS;
		}
	}
	/*******************************************************************************/




	std::string dtGroup = input.substr(dtGroupS, dtGroupE - dtGroupS + 1);
	std::smatch match;






	/********Below part is to read the date/time piece to get standard date/time string***********/
	assert(timeVec.size() < 3);

	if(timeVec.size() > 1){            
		if(dateVec.size() > 1){         //two T and two D, regardless of relative positions
			startT = timeVec[0];
			endT = timeVec[1];
			date1 = dateVec[0];
			date2 = dateVec[1];

		}else if(dateVec.size() == 1){   //two Times and one Date, regardless of....
			if((posDateS[0] > posTimeE[1]) || (posDateE[0] < posTimeS[0])){ // Time1 Time2 Date or Date Time1 Time2 -> Time1-Date to Time2-Date
				startT = timeVec[0];	
				endT = timeVec[1];
				date1 = dateVec[0];
				date2 = dateVec[0];	
			}else{ // Time1 Date Time2
				std::string conjunction = input.substr(posDateE[0]+1, posTimeS[1]-posDateE[0]-1);  
				conjunction = clear_Space_Punctuation(conjunction);
				if(std::regex_match(conjunction, match, r_to)){ //Time1 Date to Time2 
					startT = timeVec[0];	
					endT = timeVec[1];
					date1 = dateVec[0];
					date2 = dateVec[0];
				}else{//Time1 to Date Time2 
					startT = timeVec[0];
					endT = timeVec[1];

					CurrentTime CT;
					CT.catchCurrentDT();
					date1 = CT.getCurrentDate();
					date2 = dateVec[0];
				}
			}
		}else{   // Time Time 
			startT = timeVec[0];
			endT = timeVec[1];

			CurrentTime CT;
			CT.catchCurrentDT();
			date1 = CT.getCurrentDate();
			date2 = CT.getCurrentDate();
		}

	}else if(timeVec.size() == 1){
		if(dateVec.size() > 1){         //one Time and two Date, considered as timed event.
			if(posDateE[1] < posTimeS[0]){ //D1 D2 T
				startT = TRIPLE_ZERO;
				endT = timeVec[0];
				date1 = dateVec[0];
				date2 = dateVec[1];
			}else{

				if(posTimeS[0] > posDateE[0]){   // Date Time Date
					std::string conjunction = input.substr(posDateE[0]+1, posTimeS[0]-posDateE[0]-1);
					conjunction = clear_Space_Punctuation(conjunction);
					if(std::regex_match(conjunction, match, r_to)){  // Date to Time Date
						startT = TRIPLE_ZERO;
						endT = timeVec[0];
						date1 = dateVec[0];
						date2 = dateVec[1];
					}else{
						startT = timeVec[0];
						endT = TWO_THREE_FIVE_NINE_LOCATOR;
						date1 = dateVec[0];
						date2 = dateVec[1];
					}

				}else{
					startT = timeVec[0];
					endT = TWO_THREE_FIVE_NINE_LOCATOR;
					date1 = dateVec[0];
					date2 = dateVec[1];
				}

			}
		}else if(dateVec.size() == 1){   //one Time and one Date
			std::string wordBeforedtGroup = getWordBeforeGroup(input, dtGroupS);

			if(regex_match(wordBeforedtGroup, match, r_before) || regex_match(wordBeforedtGroup, match, r_by) || regex_match(wordBeforedtGroup, match, r_until) || regex_match(wordBeforedtGroup, match, r_till)){
				//considered as deadline task
				startT = QUOTE_LOCATOR;
				endT = timeVec[0];
				date1 = QUOTE_LOCATOR;
				date2 = dateVec[0];

			}else{
				if(posDateE[0] < posTimeS[0]){ // Date Time
					startT = timeVec[0];
					endT = getDefaultEndTime(startT);
					date1 = dateVec[0];
					date2 = dateVec[0];
				}else{ //Time Date
					std::string conjunction = input.substr(posTimeE[0]+1, posDateS[0]-posTimeE[0]-1);
					conjunction = clear_Space_Punctuation(conjunction);
					if(std::regex_match(conjunction, match, r_to)){  // Time to Date
						startT = timeVec[0];
						endT = getDefaultEndTime(startT);

						CurrentTime CT;
						CT.catchCurrentDT();
						date1 = CT.getCurrentDate();
						date2 = dateVec[0];
					}else{ // Time Date
						startT = timeVec[0];
						endT = getDefaultEndTime(startT);
						date1 = dateVec[0];
						date2 = dateVec[0];
					}
				}
			}
		}else{							//one Time no Date
			std::string wordBeforedtGroup = getWordBeforeGroup(input, dtGroupS);

			if(regex_match(wordBeforedtGroup, match, r_before) || regex_match(wordBeforedtGroup, match, r_by) || regex_match(wordBeforedtGroup, match, r_until) || regex_match(wordBeforedtGroup, match, r_till)){
				//considered as deadline task
				startT = QUOTE_LOCATOR;
				endT = timeVec[0];
				date1 = QUOTE_LOCATOR;
				CurrentTime CT;
				CT.catchCurrentDT();
				date2 = CT.getCurrentDate();
			}else{
				startT = timeVec[0];
				endT = getDefaultEndTime(startT);

				CurrentTime CT;
				CT.catchCurrentDT();
				date1 = CT.getCurrentDate();
				date2 = CT.getCurrentDate();
			}
		}
	}else{  // no time
		if(dateVec.size() > 1){         //Date Date
			startT = FOUR_ZERO_LOCATOR;
			endT = TWO_THREE_FIVE_NINE_LOCATOR;
			date1 = dateVec[0];
			date2 = dateVec[1];

		}else if(dateVec.size() == 1){   // Date
		//When 1 date 0 time, locator will check the TimeToTime format(e.g. 3-5 date)


			/*********enlarge the date/time Group to include possible TimeToTime piece and deadlineEvent indicator(Before, By, Till, Until)********/
			std::string pre_fix = input.substr(0, dtGroupS);
			size_t pos2 = pre_fix.find_last_not_of(' ');

			if(pos2 == std::string::npos){
				pos2 = dtGroupS - 1;
			}

			pre_fix = pre_fix.substr(0, pos2+1);
			size_t pos1 = pre_fix.find_last_of(' ');                      

			if(pos1 == std::string::npos){
				pos1 = 0;
			}else{
				pos1 = pos1 + 1;
			}
			std::string wordBeforedtGroup = input.substr(pos1, pos2-pos1+1);
			const size_t ExtendeddtGroupS = pos1;
			/***************************************************************************************************************************************/



			if(regex_match(wordBeforedtGroup, match, r_before) || regex_match(wordBeforedtGroup, match, r_by) || regex_match(wordBeforedtGroup, match, r_until) || regex_match(wordBeforedtGroup, match, r_till)){
				//considered as deadline task
				startT = QUOTE_LOCATOR;
				endT = TWO_THREE_FIVE_NINE_LOCATOR;
				date1 = QUOTE_LOCATOR;
				date2 = dateVec[0];
			}else{//check TimeToTime piece
				std::string timeS;
				std::string  timeE;
				size_t stPos;
				size_t edPos;
				size_t prePos = 0;
				std::string pre = input.substr(0, dtGroupS);
				std::string post = input.substr(dtGroupE+1, input.size()-dtGroupE-1);
				std::vector<size_t> posTimeToTimeSt;
				std::vector<size_t> posTimeToTimeEd;
				size_t postst = 0;
				size_t posted = 0;

				/*****Get all possible TimeToTime Piece from prefix*********/
				while(timeP.parseTwoTime(pre, timeS, timeE, stPos, edPos)){
					posTimeToTimeSt.push_back(stPos);
					posTimeToTimeEd.push_back(edPos);

					pre = pre.substr(edPos+1, pre.size()-edPos-1);
				}
				/************************************************************/


				if(!posTimeToTimeSt.empty()){//Prefix contains TimeToTime pieces
					std::string conjunction;

					conjunction = input.substr(posTimeToTimeEd.back()+1, posDateS[0] - posTimeToTimeEd.back() - 1);

					conjunction = clear_Space_Punctuation(conjunction);   //conjunction is the part between last TimeToTime piece and date/time Group

					if(std::regex_match(conjunction, match, r_on) || std::regex_match(conjunction, match, r_in) || std::regex_match(conjunction, match, r_at) || conjunction == QUOTE_LOCATOR){
						startT = timeS;
						endT = timeE;
						dtGroupS = ExtendeddtGroupS;

					}else{//TimeToTime pieces in prefix is not stick to the fate/time group, not counted. Then check suffix

						if(timeP.parseTwoTime(post, timeS, timeE, stPos, edPos)){

							std::string conjunction;
							conjunction = input.substr(posDateE[0]+1, stPos-0);
							conjunction = clear_Space_Punctuation(conjunction);

							if(std::regex_match(conjunction, match, r_on) || std::regex_match(conjunction, match, r_in) || std::regex_match(conjunction, match, r_at) || conjunction == QUOTE_LOCATOR){
								startT = timeS;
								endT = timeE;
								dtGroupE = edPos + 1 + dtGroupE;
							}else{
								startT = TRIPLE_ZERO;
								endT = TWO_THREE_FIVE_NINE_LOCATOR;
							}
						}else{
							startT = TRIPLE_ZERO;
							endT = TWO_THREE_FIVE_NINE_LOCATOR;
						}


					}
				}else{//Prefix doesnt contains TimeToTime pieces, and then check suffix
					if(timeP.parseTwoTime(post, timeS, timeE, stPos, edPos)){

						std::string conjunction;
						conjunction = input.substr(posDateE[0]+1, stPos - 0);
						conjunction = clear_Space_Punctuation(conjunction);

						if(std::regex_match(conjunction, match, r_on) || std::regex_match(conjunction, match, r_in) || std::regex_match(conjunction, match, r_at) || conjunction == QUOTE_LOCATOR){
							startT = timeS;
							endT = timeE;
							dtGroupE = edPos-0 + 1 + dtGroupE;
						}else{
							startT = TRIPLE_ZERO;
							endT = TWO_THREE_FIVE_NINE_LOCATOR;
						}
					}else{
						startT = TRIPLE_ZERO;
						endT = TWO_THREE_FIVE_NINE_LOCATOR;
					}
				}

				date1 = dateVec[0];
				date2 = dateVec[0];
			}

		}else{                           //no Time and no Date     Floating event
			startT = QUOTE_LOCATOR;
			endT = QUOTE_LOCATOR;
			date1 = QUOTE_LOCATOR;
			date2 = QUOTE_LOCATOR;
		}
	}

	name = getName(input, dtGroupS, dtGroupE);
	return true;
}


